<template>
  <div class="flex h-full">
    <div class="w-85 h-full p-4 flex-shrink-0 border-r flex flex-col border-gray-200 overflow-y-auto">
      <a-input class="mb-4" v-model:value.trim="state.searchName" placeholder="请输入搜索关键字" allow-clear @change="getFolderTree">
        <template #suffix v-if="!state.searchName">
          <SearchOutlined style="color: #999" />
        </template>
      </a-input>
      <a-tree
        v-if="state.treeData.length > 0"
        v-model:selectedKeys="state.selectedKeys"
        v-model:expandedKeys="state.expandedKeys"
        class="tree-warpper"
        :block-node="true"
        :tree-data="state.treeData"
        :field-names="{ title: 'name', children: 'children', key: 'id' }"
        show-icon
        default-expand-all
        @select="(_, { node }) => folderClick(node)"
      >
        <template #switcherIcon="{ switcherCls, children }">
          <caret-down-outlined :class="switcherCls" v-if="hideIcon(children)" />
        </template>
        <template #icon="{ level }">
          <template v-if="level === 0">
            <i class="iconfont icon-folder"></i>
          </template>
          <template v-if="![0, -1].includes(level)">
            <i class="iconfont icon-xiangmuerjiwenjianjia"></i>
          </template>
          <template v-if="level === -1"> </template>
        </template>
      </a-tree>
    </div>
    <div class="px-4" :style="{ width: 'calc(100% - 340px)' }">
      <DynamicForm class="mt-4" :config="dyConfig" :questions="dyQuestions" />
      <DynamicTable :tables="dyTable" :config="dyTableConfig" :icons="dyIcons" ref="fileRef">
        <!-- 面包屑 -->
        <template #title>
          <div>
            <a-breadcrumb>
              <template v-for="(item, index) in breadcrumbs" :key="index">
                <a-breadcrumb-item :class="index === breadcrumbs.length - 1 ? null : 'hierarchy'" @click="folderClick(item)">{{ item.name }}</a-breadcrumb-item>
              </template>
            </a-breadcrumb>
          </div>
        </template>
        <!-- 文件夹及文件-->
        <template #fileImg="{ record }">
          <img v-if="record.folder" class="w-11.5 h-11.5 cursor-pointer" @click="folderClick(record)" :src="personalFolder(record)" alt="" />
          <img v-else @click="fileClick(record)" class="w-11.5 h-11.5 cursor-pointer" :src="checkFileIcon(record.suffix)" alt="" />
        </template>
        <template #fileName="{ record }">
          <div>
            <p class="text-4 text-black text-opacity-65 cursor-pointer" style="margin: 0">
              <span v-if="record.folder" @click="folderClick(record)">{{ record.name }}</span>
              <span v-else @click="fileClick(record)">{{ record.name }}</span>
            </p>
          </div>
        </template>
        <template #size="{ record }">
          <div class="content fix-margin">
            <p>{{ changeByte(record.size) }}</p>
          </div>
        </template>
        <template #modifier="{ record }">
          <div class="content fix-margin">
            <!-- <p>修改人</p> -->
            <p>{{ record.modifierName }}</p>
          </div>
        </template>
        <template #updateTime="{ record }">
          <div class="content fix-margin">
            <!-- <p>修改时间</p> -->
            <p>{{ record.modifiedTime }}</p>
          </div>
        </template>
        <template #authority="{ record }">
          <div class="content fix-margin">
            <p class="over" :title="permissionDisplay(record)">{{ permissionDisplay(record) }}</p>
          </div>
        </template>
      </DynamicTable>
    </div>
  </div>
  <ViewDialog v-model:visible="state.showDetail" v-if="state.showDetail" :data="state.showData" :show-type="state.showType" @handleEdit="handleEdit" />
  <!-- 权限设置弹窗 -->
  <AuthorityDialog v-model:visible="state.showAuthority" v-if="state.showAuthority" :directoryId="state.directoryId" :title="state.name"></AuthorityDialog>
</template>

<script lang="ts" setup>
import { onMounted, computed, createVNode, getCurrentInstance, nextTick, onBeforeUnmount, reactive, ref, watch } from 'vue';
import { DynamicForm, DynamicTable } from '@/components/public-template';
import { checkFileIcon } from '@/utils/common';
import { Api, deptBatchDelete, deptGet, deptGetChildrenFolders, deptSave, fileGetPreviewFileUrl, savePermission, getPermission, fileOptlist, setAsCurrent } from '@/config/api/deptFile';
import { fileCopyFile, fileMoveFile, fileCopyFolder, fileMoveFolder } from '@/config/api/fileInfo';
import { message, Modal } from 'ant-design-vue';
import {
  DYNAMICLAYERCLEAR,
  DYNAMICLAYERTABLE,
  DYNAMICLAYERFORM,
  SEARCHSERVE,
  INPUTSERVE,
  DYNAMICLOCALICONS,
  DYNAMICLOCALTABLE,
  DYNAMICLTABLEDELETE,
  LOCALSUBSERVE,
  RESETTABLE,
  UPLOADESERVE
} from '@/mixins/subject/subject-types';
import { filter } from 'rxjs/operators';
import indexService from './index.service';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import AuthorityDialog from './components/authorityDialog.vue';
import ViewDialog from './components/viewDialog.vue';
import { changeByte, reviewFile } from '@/utils/common';
import { downloadFile } from '@/utils/useDownload';
import { SUB_SYSTEM } from '@/enums/commonEnum';
import publicFolder from '@/assets/img/fileImg/filePublicFolder.png';
import personalImg from '@/assets/img/fileImg/filePersonalFolder.png';

const state = reactive({
  searchName: '',
  selectedKeys: [],
  expandedKeys: [], //默认展开的树节点
  treeData: [],
  showData: null,
  showDetail: false,
  showAuthority: false,
  showType: '',
  level: 0,
  permission: [], // 点击文件赋值的权限参数
  filePage: [],
  visible: false, // 权限设置弹窗
  name: '', // 权限设置的文件名
  directoryId: null // 文件权限id
});
const fileRef = ref(null);
const breadcrumbs: any = ref([]);
const { proxy }: any = getCurrentInstance();
const dyConfig: any = {
  labelCol: 4,
  wrapperCol: 18,
  grid: 12, // 分栏
  style: 'table-form',
  cancelSave: true // 隐藏底部按钮
};
const dyTableConfig: any = reactive({
  name: 'deptFile',
  queryUrl: Api.deptQueryFolderWithFilePage,
  protType: 'post',
  isShowHeader: true,
  rowSelection: {
    type: 'checkbox'
  },
  params: { parentId: '', ignoreUploadingFile: true }, // ignoreUploadingFile 默认忽略C端正在上传的文件
  beforeWithMethod: (data) => {
    state.filePage = data;
    data.forEach((item) => {
      delete item.children;
      if (item.premessionList) {
        item.permissionConfiguration = permissionDisplay(item);
      }
      if (item.parentId === item.deptId) {
        item.isPermissionSettings = true;
      } else {
        item.isPermissionSettings = false;
      }
    });
    return data;
  }
});
const dyQuestions: any = reactive(indexService.getQuestions());
const dyTable: any = reactive(indexService.getTables(state.level));
const dyIcons: any = reactive(indexService.getIcons());

// 文件权限展示
function permissionDisplay(record) {
  if (record.premessionList) {
    let authorityType = {
        '2': '全部权限',
        '3': '上传/下载',
        '4': '仅预览',
        '5': '仅上传',
        '6': '仅下载'
      },
      arr = [];
    record.premessionList.forEach((item, index) => {
      arr.push(authorityType[item]);
    });
    return arr.join('、');
  }
}
// 文件图片展示
function personalFolder(record) {
  return record.id === record.deptId ? personalImg : publicFolder;
}
const subscribeSub = proxy.$NotificationFormSub
  .getParams()
  .pipe(filter((res) => res !== 0))
  .subscribe((item: any) => {
    if (item.key === INPUTSERVE && item.value.name === 'searchName') {
      // 条件查询全部文件
      dyTableConfig.params.parentId = '';
    } else if (item.key === SEARCHSERVE && !item.value?.name) {
      // 重置回到面包屑定位
      dyTableConfig.params.parentId = state.selectedKeys[0];
    } else if (item.key === LOCALSUBSERVE && item.state.name == dyTableConfig.name) {
      // 上方按钮-添加
      const params = { ...item.value, parentId: dyTableConfig.params.parentId };
      deptSave(params).then((result) => {
        if (result.success) {
          message.success(!item.value.id ? '添加成功' : '修改成功');
          getFolderTree();
          proxy.$NotificationPubSub.pushParams({ key: DYNAMICLAYERCLEAR, value: { name: 'form' } }); // 取消弹层
          proxy.$NotificationFormSub.pushParams({ key: RESETTABLE, value: { name: 'deptFile' } }); // 更新table
        }
      });
    } else if (item.key === UPLOADESERVE) {
      // 上方按钮-上传
      proxy.$NotificationFormSub.pushParams({ key: RESETTABLE, value: { name: 'deptFile' } }); // 更新table
    } else if (item.key === LOCALSUBSERVE && item.state.name == 'fileCopying') {
      // 文件复制
      fileCopyFile(item.value).then((res) => {
        if (res.success) {
          message.success('复制成功');
          proxy.$NotificationPubSub.pushParams({ key: DYNAMICLAYERCLEAR, value: { name: 'fileCopying' } }); // 取消弹层
          proxy.$NotificationFormSub.pushParams({ key: RESETTABLE, value: { name: 'deptFile' } }); // 更新table
        }
      });
    } else if (item.key === LOCALSUBSERVE && item.state.name == 'fileMoving') {
      // 文件移动
      fileMoveFile(item.value).then((res) => {
        if (res.success) {
          message.success('移动成功');
          proxy.$NotificationPubSub.pushParams({ key: DYNAMICLAYERCLEAR, value: { name: 'fileMoving' } }); // 取消弹层
          proxy.$NotificationFormSub.pushParams({ key: RESETTABLE, value: { name: 'deptFile' } }); // 更新table
        }
      });
    } else if (item.key === LOCALSUBSERVE && item.state.name == 'folderCopying') {
      // 文件夹复制
      fileCopyFolder(item.value).then((res) => {
        if (res.success) {
          message.success('复制成功');
          getFolderTree(); // 更新目录
          proxy.$NotificationPubSub.pushParams({ key: DYNAMICLAYERCLEAR, value: { name: 'folderCopying' } }); // 取消弹层
          proxy.$NotificationFormSub.pushParams({ key: RESETTABLE, value: { name: 'deptFile' } }); // 更新table
        }
      });
    } else if (item.key === LOCALSUBSERVE && item.state.name == 'folderMoving') {
      // 文件夹移动
      fileMoveFolder(item.value).then((res) => {
        if (res.success) {
          message.success('移动成功');
          getFolderTree(); // 更新目录
          proxy.$NotificationPubSub.pushParams({ key: DYNAMICLAYERCLEAR, value: { name: 'folderMoving' } }); // 取消弹层
          proxy.$NotificationFormSub.pushParams({ key: RESETTABLE, value: { name: 'deptFile' } }); // 更新table
        }
      });
    } else if (item.key === RESETTABLE) {
      getFolderTree(); // 更新目录
    }
  });
// 监听table
const subscribeSubTab = proxy.$NotificationPubSub
  .getParams()
  .pipe(filter((res) => res !== 0))
  .subscribe((item: any) => {
    if (item.key === DYNAMICLOCALTABLE && item.value.part.text === '详情') {
      // table按钮-详情
      deptGet(item.value.data.id).then((result) => {
        if (result.success) {
          state.showType = 'VIEW';
          state.showDetail = true;
          state.showData = result.data;
        }
      });
    } else if (item.key === DYNAMICLAYERTABLE && item.value.config.name === 'deptFileVersion') {
      // 拥有上传权限才能显示回滚按钮
      item.value.tables[5].handle[0].hidden = !item.value.config.params.canUpload;
      // item.value.tables[6].handle[1].hidden = !item.value.config.params.canDownload;
    } else if (item.key === DYNAMICLAYERFORM && item.value.config.title === '重命名') {
      // 全局查询完后, 回到当前层级重置
      dyTableConfig.params.parentId = state.selectedKeys[0];
    } else if (item.key === DYNAMICLOCALTABLE && item.value.part.text === '回滚到该版本' && item.value.part.state.name == 'VERSION_BACK') {
      Modal.confirm({
        title: '回滚提示',
        icon: createVNode(ExclamationCircleOutlined),
        content: '原文件将会被覆盖，是否确定回滚该文件？',
        cancelText: '取消',
        okText: '确认',
        onOk() {
          setAsCurrent(item.value.data.id).then((res) => {
            if (res.success) {
              message.success('回滚成功');
              proxy.$NotificationFormSub.pushParams({ key: RESETTABLE, value: { name: 'deptFile' } }); // 更新table
              proxy.$NotificationFormSub.pushParams({ key: RESETTABLE, value: { name: 'deptFileVersion' } }); // 更新历史版本table
            }
          });
        }
      });
    } else if (item.key === DYNAMICLOCALTABLE && item.value.part.text === '下载' && item.value.part.state.name == 'VERSION_DOWN') {
      // table按钮-版本下载
      if (downloadLimit(item.value.data.size)) {
        message.warning('该文件夹或文件已超过500M，请使用客户端下载');
        return;
      }
      downloadFile(`${Api.versionDownload}/${item.value.data.id}`, 'GET');
    } else if (item.key === DYNAMICLOCALTABLE && [item.value.part.text, item.value.part.label].includes('下载')) {
      // table按钮-下载
      if (downloadLimit(item.value.data.size)) {
        message.warning('该文件夹或文件已超过500M，请使用客户端下载');
        return;
      }
      const params = {
        id: item.value.data.id,
        folder: item.value.data.folder,
        subsystem: SUB_SYSTEM.DMS
      };
      downloadFile(Api.deptDownload, 'POST', params);
    } else if (item.key === DYNAMICLTABLEDELETE && item.value.part.label == '删除') {
      // table按钮-删除完成回调
      getFolderTree(); // 更新目录
    } else if (item.key === DYNAMICLOCALICONS && item.value.value === '下载') {
      // 上方按钮-批量下载
      if (item.state.selected.length > 0) {
        // 判断所选项目是否具有下载权限
        let isDownload, isError;
        item.state.selected.forEach((reItem) => {
          if (!reItem.canDownload) {
            message.warning(`该账号不具备【${reItem.name}】的下载权限`);
            isDownload = true;
          } else if (downloadLimit(reItem.size)) {
            message.warning(`${reItem.name}大小已超过500M，请使用客户端下载`);
            isError = true;
          }
        });
        if (isDownload || isError) return;
        const params = item.state.selected.map((reItem) => ({
          folder: reItem.folder,
          id: reItem.id,
          subsystem: SUB_SYSTEM.DMS
        }));
        downloadFile(Api.deptBatchDownload, 'POST', params);
      } else {
        message.warning('请先选中一个选项');
      }
    } else if (item.key === DYNAMICLOCALICONS && item.value.value === '删除') {
      // 上方按钮-批量删除
      if (item.state.selected.length > 0) {
        Modal.confirm({
          title: '删除提示框',
          okText: '确认',
          cancelText: '取消',
          content: '是否确认删除所选内容？',
          onOk() {
            // 判断所选项目是否具有删除权限
            let isDelete;
            item.state.selected.forEach((reItem) => {
              if (!reItem.canDelete) {
                message.warning(`该账号不具备【${reItem.name}】的删除权限`);
                isDelete = true;
              }
            });
            if (isDelete) return;
            const parameterList = item.state.selected.map((reItem) => ({
              folder: reItem.folder,
              id: reItem.id,
              subsystem: SUB_SYSTEM.DMS
            }));
            deptBatchDelete({ parameterList }).then((res) => {
              if (res.success) {
                message.success('删除成功');
                getFolderTree();
                proxy.$NotificationFormSub.pushParams({ key: RESETTABLE, value: { name: 'deptFile' } }); // 更新table
              }
            });
          }
        });
      } else {
        message.warning('请先选中一个选项');
      }
    } else if (item.key === DYNAMICLOCALTABLE && item.value.part.label == '权限设置') {
      state.directoryId = item.value.data.id;
      state.name = item.value.data.name;
      state.showAuthority = true;
    }
  });

// 添加每节点层级关系
// const hierarchicalDisplay = (arr: any, hierarchyValue: string = '') => {
//   return arr.map((item) => ({
//     hierarchy: (hierarchyValue ? `${hierarchyValue}/` : '') + item.name,
//     label: item.name,
//     value: item.id,
//     categorize: item.categorize,
//     id: item.id,
//     children: Array.isArray(item.children) ? hierarchicalDisplay(item.children, (hierarchyValue ? `${hierarchyValue}/` : '') + item.name) : null
//   }));
// };

// 下载文件是否超过上限500M
function downloadLimit(size) {
  if (size >= 524288000) {
    return true;
  }
}

const moreBtn = computed(() => !dyTableConfig.params.parentId);
watch(
  moreBtn,
  (newVal) => {
    if (newVal) {
      dyTable[6].handle[2].showKey = [
        { key: 'folder', value: true },
        { key: 'canCopy', value: true } && { key: 'canCreate', value: true } && { key: 'canDelete', value: true } && { key: 'canDownload', value: true } && {
            key: 'canEdit',
            value: true
          } && { key: 'canMove', value: true } && { key: 'canUpload', value: true }
      ];
    } else {
      dyTable[6].handle[2].showKey = [
        { key: 'folder', value: true },
        { key: 'canCopy', value: true } || { key: 'canCreate', value: true } || { key: 'canDelete', value: true } || { key: 'canDownload', value: true } || {
            key: 'canEdit',
            value: true
          } || { key: 'canMove', value: true } || { key: 'canUpload', value: true }
      ];
    }
  },
  { immediate: true }
);
// 是否是第一层级和没有上传权限
const isFirstLev = computed(() => !dyTableConfig.params.parentId || !state.permission[0]?.canUpload);
// 第一层级不可上传文件
watch(
  isFirstLev,
  (newVal) => {
    dyIcons.forEach((item) => {
      if (item.key == 'upload') item.hidden = newVal;
    });
  },
  { immediate: true }
);

// 添加按钮是否具有权限;
const isAdd = computed(() => state.permission[0]?.canCreate && state.selectedKeys[0] !== '');
watch(
  isAdd,
  (newVal) => {
    dyIcons.forEach((item) => {
      if (item.key == 'layerFrom') item.hidden = !newVal;
    });
  },
  { immediate: true }
);
// 全部层级中隐藏删除按钮
const isDelete = computed(() => state.selectedKeys[0] === '' && dyTableConfig.params.parentId === '');
watch(
  isDelete,
  (newVal) => {
    dyIcons.forEach((item) => {
      if (item.value == '删除') item.hidden = newVal;
    });
  },
  { immediate: true }
);
// 全部层级中隐藏下载按钮
const isDownload = computed(() => state.selectedKeys[0] === '' && dyTableConfig.params.parentId === '');
watch(
  isDownload,
  (newVal) => {
    dyIcons.forEach((item) => {
      if (item.value == '下载') item.hidden = newVal;
    });
  },
  { immediate: true }
);

onMounted(async () => {
  state.expandedKeys = [''];
  await getViewTree();
});

// 初始化
function getViewTree() {
  deptGetChildrenFolders({ name: '' }).then((result) => {
    if (result.success) {
      const data = { name: '全部', id: '', children: result.data, status: 0, deptId: '', level: -1 };
      if (result.data) {
        state.treeData = [filterTree(data)];
        fileOptlist({ ids: [state.treeData[0].children[0].id] }).then((res) => {
          if (res.success) {
            state.permission = res.data;
          }
        });
        state.selectedKeys = [state.treeData[0].children[0].id];
        dyTableConfig.params.parentId = state.treeData[0].children[0].id;
        let finalData = breadcrumb(state.treeData, state.treeData[0].children[0].id);
        breadcrumbs.value = finalData;
        fileRef.value.getData();
      }
    }
  });
}

// 获取项目文件目录
function getFolderTree() {
  const params = {
    name: state.searchName
  };
  deptGetChildrenFolders(params).then((result) => {
    if (result.success) {
      const data = { name: '全部', id: '', children: result.data, status: 0, deptId: '', level: -1 };
      state.treeData = [filterTree(data)];
    }
  });
}
// 点击文件夹
function folderClick(node) {
  if (node.id) {
    fileOptlist({ ids: [node.id] }).then((result) => {
      if (result.success) {
        state.permission = result.data;
      }
    });
  }

  // 修改上传按钮传参
  for (let i = 0; i < dyIcons.length; i++) {
    if (dyIcons[i].key == 'upload') {
      dyIcons[i].state.params.directoryId = node.id;
    }
  }
  // table传参
  state.selectedKeys[0] = node.id;
  state.level = node.level;
  dyTableConfig.params.parentId = node.id;
  let finalData = breadcrumb(state.treeData, node.id);
  breadcrumbs.value = finalData;
  fileRef.value.getData();
  // 隐藏节点的面包屑
  // if (breadcrumbs.value.length === 0) {
  //   breadcrumbs.value.push({
  //     id: node.id,
  //     name: node.name
  //   });
  //   return;
  // }
  // let flag = true;
  // breadcrumbs.value.forEach((item, index) => {
  //   if (item?.id === node.id) {
  //     breadcrumbs.value.splice(index + 1);
  //     flag = false;
  //   }
  // });
  // if (flag) {
  //   breadcrumbs.value.push({
  //     id: node.id,
  //     name: node.name
  //   });
  // }
}

//面包屑
function breadcrumb(arr: any, key: any, finalData: Array<any> = []) {
  for (let i = 0, len = arr.length; i < len; i++) {
    finalData.push({ name: arr[i].name, id: arr[i].id });
    if (arr[i].id === key) {
      return finalData;
    } else if (arr[i].children && arr[i].children.length >= 1) {
      if (breadcrumb(arr[i].children, key, finalData) != false) return finalData;
    }
    finalData.pop();
  }
  return false;
}
// 点击文件
function fileClick(node) {
  const params = { id: node.id, expires: 2, timeUnit: 'HOURS' };
  fileGetPreviewFileUrl(params).then((res) => {
    if (res.success && res.data) {
      reviewFile(res.data);
    }
  });
}
// 过滤树节点
const filterTree = (tmp) => {
  if (tmp.deptId !== tmp.id) {
    tmp.class = 'disable';
  }
  if (Array.isArray(tmp.children)) {
    tmp.children.forEach((child: any) => {
      filterTree(child);
    });
  }
  return tmp;
};

// 子节点全部隐藏取消父节点展开图标
const hideIcon = (children) => {
  return children.every((item) => item.class !== 'disable');
};

// 目录编辑
function handleEdit(data) {
  state.showDetail = false;
  nextTick(() => {
    state.showType = 'EDIT';
    state.showDetail = true;
    state.showData = data;
  });
}

onBeforeUnmount(() => {
  subscribeSub && subscribeSub.unsubscribe();
  proxy.$NotificationFormSub.clearParams();
  subscribeSubTab && subscribeSubTab.unsubscribe();
  proxy.$NotificationPubSub.clearParams();
});
</script>

<style lang="less" scoped>
:deep(.tree-warpper) {
  .ant-tree-switcher {
    line-height: 36px;
  }
  .ant-tree-node-content-wrapper {
    min-height: 36px;
    line-height: 36px;
    &.ant-tree-node-selected {
      background-color: #e5eefd;
      color: #005aea;
    }
  }
  .disable {
    display: none !important;
  }
}
:deep(.ant-form-item) {
  margin-bottom: 0;
}
// :deep(.ant-table-content) {
//   max-height: 200px;
//   overflow-y: scroll;
// }
.content {
  @apply text-black text-opacity-45;
  p:nth-child(2) {
    display: inline-block;
  }
}
.fix-margin {
  p {
    margin: 0px !important;
  }
}
/deep/.ant-tree-node-content-wrapper {
  display: flex;
  align-items: center;
}
/deep/.ant-tree-title {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.over {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.hierarchy {
  cursor: pointer;
}
.hierarchy:hover {
  color: #409eff;
}
</style>
